package com.smedi.ismedi.inmail.core.application.query.impl;

import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.authority.starter.util.VerifyHelper;
import com.smedi.ismedi.constructionproject.api.dto.request.ProjectListQueryRequest;
import com.smedi.ismedi.constructionproject.api.dto.response.resp.ProjectResp;
import com.smedi.ismedi.constructionproject.api.feign.RemoteConstructionProjectFeignApi;
import com.smedi.ismedi.inmail.core.application.command.*;
import com.smedi.ismedi.inmail.core.application.query.SafetyBoardQueryService;
import com.smedi.ismedi.inmail.core.application.query.vo.*;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.Labor;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.LaborProjectAssignment;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.SafetyEducationVo;
import com.smedi.ismedi.inmail.core.domain.dto.*;
import com.smedi.ismedi.inmail.core.port.adapter.service.*;
import com.smedi.ismedi.organization.api.dto.response.resp.OrganizationResp;
import com.smedi.ismedi.video.monitor.api.dto.response.MonitorSettingCountResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.EducationTypeEnum.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.EpcTypeEnum.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.GenderStatusEnum.FEMALE;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.GenderStatusEnum.MALE;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.LaborStatus.IN;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.MonitorTypeEnum.NOT_INSTALLED;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.MonitorTypeEnum.STOPPED;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.ProjectStatusEnum.*;
import static com.smedi.ismedi.inmail.core.infrastructure.constant.ConstantField.TimeTypeEnum.*;
import static com.smedi.ismedi.web.starter.thread.ThreadPool.IO_INSTANCE;


/**
 * 安全看板应用服务实现类
 *
 * @author niuyanling
 * @date 2021/10/222
 */
@Service
@AllArgsConstructor
@Slf4j
public class SafetyBoardQueryServiceImpl implements SafetyBoardQueryService {
    private final RemoteConstructionProjectFeignApi remoteConstructionProjectFeignApi;
    private final AuthorityUtil authorityUtil;
    private final ProjectRemoteService projectRemoteService;
    private final OrganizationRemoteService organizationRemoteService;
    private final SafetyCheckRemoteApi safetyCheckRemoteApi;
    private final SafetyEducationRemoteApi safetyEducationRemoteApi;
    private final VideoMonitorRemoteApi videoMonitorRemoteApi;
    private final LaborRemoteApi laborRemoteApi;
    private final MajorHazardRemoteApi majorHazardRemoteApi;
    private final DangerSourceRemoteApi dangerSourceRemoteApi;
    private final HiddenDangerRemoteApi hiddenDangerRemoteApi;
    private final VerifyHelper verifyHelper;

    @Override
    public ProjectStatisticsVo getProjectStatistics() {
        ProjectStatisticsVo projectStatisticsVo = ProjectStatisticsVo.builder()
                .totalNum(new BigDecimal("0")).build();

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return projectStatisticsVo;
        }

        // 获取全部项目
        List<ProjectResp> projects = projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build());

        BigDecimal totalNum = new BigDecimal("0");

        BigDecimal constructingNum = new BigDecimal("0");
        BigDecimal constructingAndSelfSupportNum = new BigDecimal("0");
        BigDecimal constructingAndConsortiumNum = new BigDecimal("0");
        BigDecimal constructingAndSelfSupportConsortiumNum = new BigDecimal("0");

        BigDecimal notStartedNum = new BigDecimal("0");
        BigDecimal notStartedAndSelfSupportNum = new BigDecimal("0");
        BigDecimal notStartedAndConsortiumNum = new BigDecimal("0");
        BigDecimal notStartedAndSelfSupportConsortiumNum = new BigDecimal("0");

        BigDecimal stoppedNum = new BigDecimal("0");
        BigDecimal stoppedAndSelfSupportNum = new BigDecimal("0");
        BigDecimal stoppedAndConsortiumNum = new BigDecimal("0");
        BigDecimal stoppedAndSelfSupportConsortiumNum = new BigDecimal("0");

        BigDecimal finishedNum = new BigDecimal("0");
        BigDecimal finishedAndSelfSupportNum = new BigDecimal("0");
        BigDecimal finishedAndConsortiumNum = new BigDecimal("0");
        BigDecimal finishedAndSelfSupportConsortiumNum = new BigDecimal("0");

        BigDecimal completedNum = new BigDecimal("0");
        BigDecimal completedAndSelfSupportNum = new BigDecimal("0");
        BigDecimal completedAndConsortiumNum = new BigDecimal("0");
        BigDecimal completedAndSelfSupportConsortiumNum = new BigDecimal("0");

        BigDecimal selfSupportNum = new BigDecimal("0");
        BigDecimal consortiumNum = new BigDecimal("0");
        BigDecimal selfSupportConsortiumNum = new BigDecimal("0");


        for (ProjectResp project : projects) {
            totalNum = totalNum.add(new BigDecimal("1"));

            // 建设中
            if (project.getProjectStatus().equals(CONSTRUCTING.name())) {
                constructingNum = constructingNum.add(new BigDecimal("1"));
                if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                    constructingAndSelfSupportNum = constructingAndSelfSupportNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(CONSORTIUM.name())) {
                    constructingAndConsortiumNum = constructingAndConsortiumNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    constructingAndSelfSupportConsortiumNum = constructingAndSelfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            // 未开工
            if (project.getProjectStatus().equals(NOT_STARTED.name())) {
                notStartedNum = notStartedNum.add(new BigDecimal("1"));
                if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                    notStartedAndSelfSupportNum = notStartedAndSelfSupportNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(CONSORTIUM.name())) {
                    notStartedAndConsortiumNum = notStartedAndConsortiumNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    notStartedAndSelfSupportConsortiumNum = notStartedAndSelfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            // 停工
            if (project.getProjectStatus().equals(STOPPED.name())) {
                stoppedNum = stoppedNum.add(new BigDecimal("1"));
                if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                    stoppedAndSelfSupportNum = stoppedAndSelfSupportNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(CONSORTIUM.name())) {
                    stoppedAndConsortiumNum = stoppedAndConsortiumNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    stoppedAndSelfSupportConsortiumNum = stoppedAndSelfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            // 完工
            if (project.getProjectStatus().equals(FINISHED.name())) {
                finishedNum = finishedNum.add(new BigDecimal("1"));
                if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                    finishedAndSelfSupportNum = finishedAndSelfSupportNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(CONSORTIUM.name())) {
                    finishedAndConsortiumNum = finishedAndConsortiumNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    finishedAndSelfSupportConsortiumNum = finishedAndSelfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            // 竣工
            if (project.getProjectStatus().equals(COMPLETED.name())) {
                completedNum = completedNum.add(new BigDecimal("1"));
                if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                    completedAndSelfSupportNum = completedAndSelfSupportNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(CONSORTIUM.name())) {
                    completedAndConsortiumNum = completedAndConsortiumNum.add(new BigDecimal("1"));
                }
                if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                    completedAndSelfSupportConsortiumNum = completedAndSelfSupportConsortiumNum.add(new BigDecimal("1"));
                }
            }

            // 自营
            if (project.getEpcType().equals(SELF_SUPPORT.name())) {
                selfSupportNum = selfSupportNum.add(new BigDecimal("1"));
            }

            // 自营
            if (project.getEpcType().equals(CONSORTIUM.name())) {
                consortiumNum = consortiumNum.add(new BigDecimal("1"));
            }

            // 自营
            if (project.getEpcType().equals(SELF_SUPPORT_CONSORTIUM.name())) {
                selfSupportConsortiumNum = selfSupportConsortiumNum.add(new BigDecimal("1"));
            }
        }

        ArrayList<StatisticsNodeVo> constructingStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(SELF_SUPPORT.name()).number(constructingAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(CONSORTIUM.name()).number(constructingAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(SELF_SUPPORT_CONSORTIUM.name()).number(constructingAndSelfSupportConsortiumNum).build()));
        ArrayList<StatisticsNodeVo> notStartedStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(SELF_SUPPORT.name()).number(notStartedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(CONSORTIUM.name()).number(notStartedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(SELF_SUPPORT_CONSORTIUM.name()).number(notStartedAndSelfSupportConsortiumNum).build()));
        ArrayList<StatisticsNodeVo> stoppedStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(SELF_SUPPORT.name()).number(stoppedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(CONSORTIUM.name()).number(stoppedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(SELF_SUPPORT_CONSORTIUM.name()).number(stoppedAndSelfSupportConsortiumNum).build()));
        ArrayList<StatisticsNodeVo> finishedStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(SELF_SUPPORT.name()).number(finishedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(CONSORTIUM.name()).number(finishedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(SELF_SUPPORT_CONSORTIUM.name()).number(finishedAndSelfSupportConsortiumNum).build()));
        ArrayList<StatisticsNodeVo> completedStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(SELF_SUPPORT.name()).number(completedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(CONSORTIUM.name()).number(completedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(SELF_SUPPORT_CONSORTIUM.name()).number(completedAndSelfSupportConsortiumNum).build()));

        ArrayList<StatisticsNodeVo> selfSupportStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(CONSTRUCTING.name()).number(constructingAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(NOT_STARTED.name()).number(notStartedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(STOPPED.name()).number(stoppedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(FINISHED.name()).number(finishedAndSelfSupportNum).build(),
                StatisticsNodeVo.builder().name(COMPLETED.name()).number(completedAndSelfSupportNum).build()));
        ArrayList<StatisticsNodeVo> consortiumStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(CONSTRUCTING.name()).number(constructingAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(NOT_STARTED.name()).number(notStartedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(STOPPED.name()).number(stoppedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(FINISHED.name()).number(finishedAndConsortiumNum).build(),
                StatisticsNodeVo.builder().name(COMPLETED.name()).number(completedAndConsortiumNum).build()));
        ArrayList<StatisticsNodeVo> selfSupportConsortiumStatistics = new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name(CONSTRUCTING.name()).number(constructingAndSelfSupportConsortiumNum).build(),
                StatisticsNodeVo.builder().name(NOT_STARTED.name()).number(notStartedAndSelfSupportConsortiumNum).build(),
                StatisticsNodeVo.builder().name(STOPPED.name()).number(stoppedAndSelfSupportConsortiumNum).build(),
                StatisticsNodeVo.builder().name(FINISHED.name()).number(finishedAndSelfSupportConsortiumNum).build(),
                StatisticsNodeVo.builder().name(COMPLETED.name()).number(completedAndSelfSupportConsortiumNum).build()));

        StatisticsNodeVo constructing = StatisticsNodeVo.builder()
                .name(CONSTRUCTING.name())
                .number(constructingNum)
                .statisticsNodes(constructingStatistics)
                .build();
        StatisticsNodeVo notStarted = StatisticsNodeVo.builder()
                .name(NOT_STARTED.name())
                .number(notStartedNum)
                .statisticsNodes(notStartedStatistics)
                .build();
        StatisticsNodeVo stopped = StatisticsNodeVo.builder()
                .name(STOPPED.name())
                .number(stoppedNum)
                .statisticsNodes(stoppedStatistics)
                .build();
        StatisticsNodeVo finished = StatisticsNodeVo.builder()
                .name(FINISHED.name())
                .number(finishedNum)
                .statisticsNodes(finishedStatistics)
                .build();
        StatisticsNodeVo completed = StatisticsNodeVo.builder()
                .name(COMPLETED.name())
                .number(completedNum)
                .statisticsNodes(completedStatistics)
                .build();
        StatisticsNodeVo selfSupport = StatisticsNodeVo.builder()
                .name(SELF_SUPPORT.name())
                .number(selfSupportNum)
                .statisticsNodes(selfSupportStatistics)
                .build();
        StatisticsNodeVo consortium = StatisticsNodeVo.builder()
                .name(CONSORTIUM.name())
                .number(consortiumNum)
                .statisticsNodes(consortiumStatistics)
                .build();
        StatisticsNodeVo selfSupportConsortium = StatisticsNodeVo.builder()
                .name(SELF_SUPPORT_CONSORTIUM.name())
                .number(selfSupportConsortiumNum)
                .statisticsNodes(selfSupportConsortiumStatistics)
                .build();

        projectStatisticsVo.setTotalNum(totalNum);
        projectStatisticsVo.setStatisticsNodes(new ArrayList<>(Arrays.asList(constructing, notStarted, stopped, finished, completed, selfSupport, consortium, selfSupportConsortium)));

        return projectStatisticsVo;
    }

    @Override
    public LaborStatisticsVo getLaborStatistics() {

        LaborStatisticsVo laborStatisticsVo = LaborStatisticsVo.builder()
                .laborOrganizationInfos(new ArrayList<>())
                .laborProjectInfos(new ArrayList<>())
                .laborAgeInfos(new ArrayList<>())
                .laborJobInfos(new ArrayList<>())
                .highAgeLaborGenderInfos(new ArrayList<>())
                .highAgeLaborEpcTypeInfos(new ArrayList<>())
                .build();

        List<StatisticsInfoVo> laborOrganizationInfos = new ArrayList<>();
        List<StatisticsInfoVo> laborProjectInfos = new ArrayList<>();
        List<StatisticsInfoVo> laborAgeInfos = new ArrayList<>();
        List<StatisticsInfoVo> laborJobInfos = new ArrayList<>();
        List<StatisticsInfoVo> genderHighAgeGenderInfos = new ArrayList<>();
        List<StatisticsInfoVo> epcTypeHighAgeEpcTypeInfos = new ArrayList<>();
        List<StatisticsInfoVo> laborProjectInShanghaiInfos = new ArrayList<>();
        List<StatisticsInfoVo> laborProjectHighInShanghaiInfos = new ArrayList<>();

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<Labor>> allLabors = new AtomicReference<>(new ArrayList<>());

        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return laborStatisticsVo;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allLabors.set(laborRemoteApi.getLaborList(LaborQuery.builder().projectIds(projectIds).status(IN.name()).build())), IO_INSTANCE)
        ).join();

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>(128);
        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp projectResp : allProjects.get()) {
            projectIdOrganizationIdMap.put(projectResp.getId(), projectResp.getHrOrganizationId());
            projectIdProjectMap.put(projectResp.getId(), projectResp);
        }

        Map<Long, OrganizationResp> organizationIdOrganizationMap = new HashMap<>(128);
        for (OrganizationResp organizationResp : allOrganizations.get()) {
            organizationIdOrganizationMap.put(organizationResp.getId(), organizationResp);
        }

        Map<Long, StatisticsInfoVo> organizationIdOrganizationInfoMap = new HashMap<>(128);
        Map<Long, StatisticsInfoVo> projectIdProjectInfoMap = new HashMap<>(128);
        Map<String, StatisticsInfoVo> jobJobInfoMap = new HashMap<>(128);
        Map<String, StatisticsInfoVo> genderHighAgeGenderInfoMap = new HashMap<>(128);
        Map<String, StatisticsInfoVo> epcTypeHighAgeEpcTypeInfoMap = new HashMap<>(128);
        BigDecimal totalNum = new BigDecimal("0");
        BigDecimal highAgeNum = new BigDecimal("0");

        BigDecimal ageTo19Number = new BigDecimal("0");
        BigDecimal ageFrom20To29Number = new BigDecimal("0");
        BigDecimal ageFrom30To39Number = new BigDecimal("0");
        BigDecimal ageFrom40To49Number = new BigDecimal("0");
        BigDecimal ageFrom50To59Number = new BigDecimal("0");
        BigDecimal ageFrom60Number = new BigDecimal("0");

        BigDecimal inShanghai = new BigDecimal("0");
        BigDecimal outShanghai = new BigDecimal("0");

        BigDecimal highInShanghai = new BigDecimal("0");
        BigDecimal highOutShanghai = new BigDecimal("0");


        for (Labor labor : allLabors.get()) {
            LaborProjectAssignment laborProjectAssignment = labor.getLaborProjectAssignment();
            if (null == laborProjectAssignment) {
                continue;
            }
            Long projectId = laborProjectAssignment.getProjectId();
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            OrganizationResp organization = organizationIdOrganizationMap.get(organizationId);
            ProjectResp project = projectIdProjectMap.get(projectId);


            if (project.getProjectAddress() != null && project.getProjectAddress().contains("上海市")) {
                inShanghai = inShanghai.add(BigDecimal.valueOf(1));
            }
            if (project.getProjectAddress() != null && !project.getProjectAddress().contains("上海市")) {
                outShanghai = outShanghai.add(BigDecimal.valueOf(1));
            }


            // 总数
            totalNum = totalNum.add(new BigDecimal("1"));

            // 统计主体院信息
            StatisticsInfoVo organizationInfoByOrganizationId = organizationIdOrganizationInfoMap.getOrDefault(organizationId, StatisticsInfoVo.builder().name(organization.getShortName()).number(new BigDecimal("0")).build());
            organizationInfoByOrganizationId.setNumber(organizationInfoByOrganizationId.getNumber().add(new BigDecimal("1")));
            organizationIdOrganizationInfoMap.put(organizationId, organizationInfoByOrganizationId);

            // 统计项目信息
            StatisticsInfoVo projectInfoByProjectId = projectIdProjectInfoMap.getOrDefault(projectId, StatisticsInfoVo.builder().name(project.getProjectShortName()).number(new BigDecimal("0")).build());
            projectInfoByProjectId.setNumber(projectInfoByProjectId.getNumber().add(new BigDecimal("1")));
            projectIdProjectInfoMap.put(projectId, projectInfoByProjectId);

            // 统计年龄信息
            LocalDate now = LocalDate.now();
            BigDecimal age = new BigDecimal(ChronoUnit.YEARS.between(labor.getBirthday(), now));

            if (age.compareTo(new BigDecimal("20")) < 0) {
                ageTo19Number = ageTo19Number.add(new BigDecimal("1"));
            }
            if (age.compareTo(new BigDecimal("20")) >= 0 && age.compareTo(new BigDecimal("30")) < 0) {
                ageFrom20To29Number = ageFrom20To29Number.add(new BigDecimal("1"));
            }
            if (age.compareTo(new BigDecimal("30")) >= 0 && age.compareTo(new BigDecimal("40")) < 0) {
                ageFrom30To39Number = ageFrom30To39Number.add(new BigDecimal("1"));
            }
            if (age.compareTo(new BigDecimal("40")) >= 0 && age.compareTo(new BigDecimal("50")) < 0) {
                ageFrom40To49Number = ageFrom40To49Number.add(new BigDecimal("1"));
            }
            if (age.compareTo(new BigDecimal("50")) >= 0 && age.compareTo(new BigDecimal("60")) < 0) {
                ageFrom50To59Number = ageFrom50To59Number.add(new BigDecimal("1"));
            }
            if (age.compareTo(new BigDecimal("60")) >= 0) {
                ageFrom60Number = ageFrom60Number.add(new BigDecimal("1"));
            }

            // 统计工种信息
            String job = laborProjectAssignment.getJob();
            StatisticsInfoVo jobInfoByJob = jobJobInfoMap.getOrDefault(job, StatisticsInfoVo.builder().name(job).number(new BigDecimal("0")).build());
            jobInfoByJob.setNumber(jobInfoByJob.getNumber().add(new BigDecimal("1")));
            jobJobInfoMap.put(job, jobInfoByJob);
            // 统计高龄人员信息
            String gender = labor.getGender();
            if ((gender.equals(FEMALE.name()) && age.compareTo(new BigDecimal("45")) >= 0 && age.compareTo(new BigDecimal("50")) < 0) || (gender.equals(MALE.name()) && age.compareTo(new BigDecimal("55")) >= 0 && age.compareTo(new BigDecimal("60")) < 0)) {
                highAgeNum = highAgeNum.add(new BigDecimal("1"));

                if (project.getProjectAddress() != null && project.getProjectAddress().contains("上海市")) {
                    highInShanghai = highInShanghai.add(BigDecimal.valueOf(1));
                }
                if (project.getProjectAddress() != null && !project.getProjectAddress().contains("上海市")) {
                    highOutShanghai = highOutShanghai.add(BigDecimal.valueOf(1));
                }

                // 统计性别信息
                StatisticsInfoVo HighAgeGenderInfoByGender = genderHighAgeGenderInfoMap.getOrDefault(gender, StatisticsInfoVo.builder().name(gender).number(new BigDecimal("0")).build());
                HighAgeGenderInfoByGender.setNumber(HighAgeGenderInfoByGender.getNumber().add(new BigDecimal("1")));
                genderHighAgeGenderInfoMap.put(gender, HighAgeGenderInfoByGender);

                // 统计EPC类型信息
                String epcType = project.getEpcType();
                StatisticsInfoVo HighAgeEpcTypeInfoByEpcType = epcTypeHighAgeEpcTypeInfoMap.getOrDefault(epcType, StatisticsInfoVo.builder().name(epcType).number(new BigDecimal("0")).build());
                HighAgeEpcTypeInfoByEpcType.setNumber(HighAgeEpcTypeInfoByEpcType.getNumber().add(new BigDecimal("1")));
                epcTypeHighAgeEpcTypeInfoMap.put(epcType, HighAgeEpcTypeInfoByEpcType);
            }
        }

        laborStatisticsVo.setTotalNum(totalNum);

        if (totalNum.compareTo(new BigDecimal("0")) == 0) {
            return laborStatisticsVo;
        }

        StatisticsInfoVo inShanghaiInfoVo = new StatisticsInfoVo();
        inShanghaiInfoVo.setNumber(inShanghai);
        inShanghaiInfoVo.setName("在沪项目人数");
        inShanghaiInfoVo.setDisplayOrder(0);
        inShanghaiInfoVo.setRate(inShanghai.divide(totalNum, 3, RoundingMode.HALF_UP));

        StatisticsInfoVo outShanghaiInfoVo = new StatisticsInfoVo();
        outShanghaiInfoVo.setNumber(outShanghai);
        outShanghaiInfoVo.setName("非沪项目人数");
        outShanghaiInfoVo.setDisplayOrder(1);
        outShanghaiInfoVo.setRate(outShanghai.divide(totalNum, 3, RoundingMode.HALF_UP));

        laborProjectInShanghaiInfos.add(inShanghaiInfoVo);
        laborProjectInShanghaiInfos.add(outShanghaiInfoVo);

        StatisticsInfoVo highInShanghaiInfoVo = new StatisticsInfoVo();
        highInShanghaiInfoVo.setNumber(highInShanghai);
        highInShanghaiInfoVo.setName("在沪项目高龄人数");
        highInShanghaiInfoVo.setDisplayOrder(0);
        highInShanghaiInfoVo.setRate(highInShanghai.divide(totalNum, 3, RoundingMode.HALF_UP));

        StatisticsInfoVo highOutShanghaiInfoVo = new StatisticsInfoVo();
        highOutShanghaiInfoVo.setNumber(highOutShanghai);
        highOutShanghaiInfoVo.setName("非沪项目高龄人数");
        highOutShanghaiInfoVo.setDisplayOrder(1);
        highOutShanghaiInfoVo.setRate(highOutShanghai.divide(totalNum, 3, RoundingMode.HALF_UP));

        laborProjectHighInShanghaiInfos.add(highInShanghaiInfoVo);
        laborProjectHighInShanghaiInfos.add(highOutShanghaiInfoVo);


        // 装载主体院信息
        if (!organizationIdOrganizationInfoMap.isEmpty()) {
            laborOrganizationInfos = organizationIdOrganizationInfoMap.values().stream().sorted(Comparator.comparing(StatisticsInfoVo::getNumber).reversed()).collect(Collectors.toList());
            for (StatisticsInfoVo laborOrganizationInfo : laborOrganizationInfos) {
                laborOrganizationInfo.setRate(laborOrganizationInfo.getNumber().divide(totalNum, 3, RoundingMode.HALF_UP));
            }
        }

        // 装载项目信息
        if (!projectIdProjectInfoMap.isEmpty()) {
            laborProjectInfos = projectIdProjectInfoMap.values().stream().sorted(Comparator.comparing(StatisticsInfoVo::getNumber).reversed()).collect(Collectors.toList());
            for (StatisticsInfoVo laborProjectInfo : laborProjectInfos) {
                laborProjectInfo.setRate(laborProjectInfo.getNumber().divide(totalNum, 3, RoundingMode.HALF_UP));
            }
        }

        // 装载年龄信息
        laborAgeInfos.add(StatisticsInfoVo.builder().name("20以下").number(ageTo19Number).rate(ageTo19Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());
        laborAgeInfos.add(StatisticsInfoVo.builder().name("20~29").number(ageFrom20To29Number).rate(ageFrom20To29Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());
        laborAgeInfos.add(StatisticsInfoVo.builder().name("30~39").number(ageFrom30To39Number).rate(ageFrom30To39Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());
        laborAgeInfos.add(StatisticsInfoVo.builder().name("40~49").number(ageFrom40To49Number).rate(ageFrom40To49Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());
        laborAgeInfos.add(StatisticsInfoVo.builder().name("50~59").number(ageFrom50To59Number).rate(ageFrom50To59Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());
        laborAgeInfos.add(StatisticsInfoVo.builder().name("60及以上").number(ageFrom60Number).rate(ageFrom60Number.divide(totalNum, 3, RoundingMode.HALF_UP)).build());

        // 装载工种信息
        if (!jobJobInfoMap.isEmpty()) {
            laborJobInfos = jobJobInfoMap.values().stream().sorted(Comparator.comparing(StatisticsInfoVo::getNumber).reversed()).collect(Collectors.toList());
            for (StatisticsInfoVo laborJobInfo : laborJobInfos) {
                laborJobInfo.setRate(laborJobInfo.getNumber().divide(totalNum, 3, RoundingMode.HALF_UP));
            }
        }

        // 装载高龄性别信息
        if (!genderHighAgeGenderInfoMap.isEmpty()) {
            genderHighAgeGenderInfos = new ArrayList<>(genderHighAgeGenderInfoMap.values());
            for (StatisticsInfoVo genderHighAgeGenderInfo : genderHighAgeGenderInfos) {
                genderHighAgeGenderInfo.setRate(genderHighAgeGenderInfo.getNumber().divide(highAgeNum, 3, RoundingMode.HALF_UP));
            }
        }

        // 装载高龄Epc类型信息
        if (!epcTypeHighAgeEpcTypeInfoMap.isEmpty()) {
            ArrayList<String> orderRule = new ArrayList<>(Arrays.asList(SELF_SUPPORT.name(), SELF_SUPPORT_CONSORTIUM.name(), CONSORTIUM.name()));
            epcTypeHighAgeEpcTypeInfos = new ArrayList<>(epcTypeHighAgeEpcTypeInfoMap.values());
            epcTypeHighAgeEpcTypeInfos.sort(Comparator.comparingInt(o -> orderRule.indexOf(o.getName())));
            for (StatisticsInfoVo epcTypeHighAgeEpcTypeInfo : epcTypeHighAgeEpcTypeInfos) {
                epcTypeHighAgeEpcTypeInfo.setRate(epcTypeHighAgeEpcTypeInfo.getNumber().divide(highAgeNum, 3, RoundingMode.HALF_UP));
            }
        }

        laborStatisticsVo.setLaborOrganizationInfos(laborOrganizationInfos);
        laborStatisticsVo.setLaborProjectInfos(laborProjectInfos);
        laborStatisticsVo.setLaborAgeInfos(laborAgeInfos);
        laborStatisticsVo.setLaborJobInfos(laborJobInfos);
        laborStatisticsVo.setHighAgeLaborGenderInfos(genderHighAgeGenderInfos);
        laborStatisticsVo.setHighAgeLaborEpcTypeInfos(epcTypeHighAgeEpcTypeInfos);
        laborStatisticsVo.setHighAgeNum(highAgeNum);
        laborStatisticsVo.setLaborProjectInShanghaiInfos(laborProjectInShanghaiInfos);
        laborStatisticsVo.setHighLaborProjectInShanghaiInfos(laborProjectHighInShanghaiInfos);

        return laborStatisticsVo;
    }

    @Override
    public ProjectStatisticsByRegionVo getProjectStatisticsByRegion(String provinceName) {
        List<ProjectResp> projects = remoteConstructionProjectFeignApi.getProjectList(ProjectListQueryRequest.builder().build()).getData();

        BigDecimal totalNum = new BigDecimal("0");
        BigDecimal totalNumByRegion = new BigDecimal("0");
        BigDecimal constructingNum = new BigDecimal("0");
        BigDecimal constructingNumByRegion = new BigDecimal("0");

        for (ProjectResp project : projects) {
            totalNum = totalNum.add(new BigDecimal("1"));
            if (project.getProjectStatus().equals(CONSTRUCTING.name())) {
                constructingNum = constructingNum.add(new BigDecimal("1"));
            }
            if (project.getProjectAddressProvince().equals(provinceName)) {
                totalNumByRegion = totalNumByRegion.add(new BigDecimal("1"));
                if (project.getProjectStatus().equals(CONSTRUCTING.name())) {
                    constructingNumByRegion = constructingNumByRegion.add(new BigDecimal("1"));
                }
            }
        }

        return ProjectStatisticsByRegionVo.builder()
                .totalNumByRegion(totalNumByRegion)
                .totalRate(totalNumByRegion.multiply(new BigDecimal("100")).divide(totalNum, 1, RoundingMode.HALF_UP))
                .constructingNumByRegion(constructingNumByRegion)
                .constructingRate(constructingNumByRegion.multiply(new BigDecimal("100")).divide(constructingNum, 1, RoundingMode.HALF_UP))
                .build();
    }

    @Override
    public List<StatisticsNodeVo> getSafetyCheckInstituteStatics(SafetyCheckInstituteStatisticsCommand safetyCheckInstituteStatisticsCommand) {
        List<StatisticsNodeVo> statisticsNodeVos = new ArrayList<>();

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());

        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return statisticsNodeVos;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder().checkStartDateTime(safetyCheckInstituteStatisticsCommand.getStartTime()).checkEndDateTime(safetyCheckInstituteStatisticsCommand.getEndTime().minusSeconds(1L)).submitted(true).build())), IO_INSTANCE)
        ).join();

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>();
        Map<Long, BigDecimal> organizationIdConstructingNumMap = new HashMap<>();
        for (ProjectResp project : allProjects.get()) {
            projectIdOrganizationIdMap.put(project.getId(), project.getHrOrganizationId());
            if (project.getProjectStatus().equals(CONSTRUCTING.name())) {
                BigDecimal constructingNum = organizationIdConstructingNumMap.getOrDefault(project.getHrOrganizationId(), new BigDecimal("0")).add(new BigDecimal("1"));
                organizationIdConstructingNumMap.put(project.getHrOrganizationId(), constructingNum);
            }
        }

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        Map<Long, Map<String, BigDecimal>> organizationIdQualityNumberMap = new HashMap<>();
        for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
            Long projectId = safetyCheckVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            Map<String, BigDecimal> qualityNumberByOrganizationIdMap = organizationIdQualityNumberMap.getOrDefault(organizationId, new HashMap<>());
            BigDecimal numberByOrganizationIdAndQuality = qualityNumberByOrganizationIdMap.getOrDefault(safetyCheckVo.getSafetyCheckQuality(), new BigDecimal("0"));
            numberByOrganizationIdAndQuality = numberByOrganizationIdAndQuality.add(new BigDecimal("1"));
            qualityNumberByOrganizationIdMap.put(safetyCheckVo.getSafetyCheckQuality(), numberByOrganizationIdAndQuality);
            organizationIdQualityNumberMap.put(organizationId, qualityNumberByOrganizationIdMap);
        }

        for (OrganizationResp organization : allOrganizations.get()) {
            if (!organization.getType().equals(HrOrganizationTypeEnum.PROJECT_MANAGEMENT_ORGANIZATION.name())) {
                continue;
            }
            Map<String, BigDecimal> qualityNumberByOrganizationIdMap = organizationIdQualityNumberMap.getOrDefault(organization.getId(), new HashMap<>());
            BigDecimal majorCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("主体院检查", new BigDecimal("0"));
            BigDecimal projectCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("项目部检查", new BigDecimal("0"));
            BigDecimal leaderCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("总院检查", new BigDecimal("0"));
            BigDecimal totalNum = majorCheckNum.add(projectCheckNum).add(leaderCheckNum);
            BigDecimal constructingNum = organizationIdConstructingNumMap.getOrDefault(organization.getId(), new BigDecimal("0"));
            statisticsNodeVos.add(StatisticsNodeVo.builder()
                    .name(organization.getShortName())
                    .number(totalNum)
                    .displayOrder(organization.getDisplayOrder())
                    .statisticsNodes(new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name("项目部检查").number(projectCheckNum).build(),
                            StatisticsNodeVo.builder().name("主体院检查").number(majorCheckNum).build(),
                            StatisticsNodeVo.builder().name("总院检查").number(leaderCheckNum).build(),
                            StatisticsNodeVo.builder().name("在建项目总数").number(constructingNum).build(),
                            StatisticsNodeVo.builder().name("项目平均检查数").number(constructingNum.compareTo(new BigDecimal("0")) == 0 ? new BigDecimal("0") : totalNum.divide(constructingNum, 3, RoundingMode.HALF_UP)).build())))
                    .build());
        }

        return statisticsNodeVos.stream().sorted(Comparator.comparing(StatisticsNodeVo::getDisplayOrder)).collect(Collectors.toList());
    }

    @Override
    public List<StatisticsNodeVo> getSafetyCheckOrganizationStatics(SafetyCheckOrganizationStatisticsCommand safetyCheckOrganizationStatisticsCommand) {
        List<StatisticsNodeVo> statisticsNodeVos = new ArrayList<>();

        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return statisticsNodeVos;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder().checkStartDateTime(safetyCheckOrganizationStatisticsCommand.getStartTime()).checkEndDateTime(safetyCheckOrganizationStatisticsCommand.getEndTime().minusSeconds(1L)).submitted(true).build())), IO_INSTANCE)
        ).join();


        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        Map<Long, Map<String, BigDecimal>> projectIdQualityNumberMap = new HashMap<>();
        for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
            Long projectId = safetyCheckVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            Map<String, BigDecimal> qualityNumberByOrganizationIdMap = projectIdQualityNumberMap.getOrDefault(projectId, new HashMap<>());
            BigDecimal numberByOrganizationIdAndQuality = qualityNumberByOrganizationIdMap.getOrDefault(safetyCheckVo.getSafetyCheckQuality(), new BigDecimal("0"));
            numberByOrganizationIdAndQuality = numberByOrganizationIdAndQuality.add(new BigDecimal("1"));
            qualityNumberByOrganizationIdMap.put(safetyCheckVo.getSafetyCheckQuality(), numberByOrganizationIdAndQuality);
            projectIdQualityNumberMap.put(projectId, qualityNumberByOrganizationIdMap);
        }

        for (ProjectResp project : allProjects.get()) {
            Map<String, BigDecimal> qualityNumberByOrganizationIdMap = projectIdQualityNumberMap.getOrDefault(project.getId(), new HashMap<>());
            BigDecimal majorCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("主体院检查", new BigDecimal("0"));
            BigDecimal projectCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("项目部检查", new BigDecimal("0"));
            BigDecimal leaderCheckNum = qualityNumberByOrganizationIdMap.getOrDefault("总院检查", new BigDecimal("0"));
            BigDecimal totalNum = majorCheckNum.add(projectCheckNum).add(leaderCheckNum);
            BigDecimal constructingNum = new BigDecimal(projectIds.size());
            statisticsNodeVos.add(StatisticsNodeVo.builder()
                    .name(project.getProjectShortName())
                    .number(qualityNumberByOrganizationIdMap.getOrDefault("项目部检查", new BigDecimal("0")).add(qualityNumberByOrganizationIdMap.getOrDefault("主体院检查", new BigDecimal("0"))).add(qualityNumberByOrganizationIdMap.getOrDefault("总院检查", new BigDecimal("0"))))
                    .displayOrder(project.getId().intValue())
                    .statisticsNodes(new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name("项目部检查").number(qualityNumberByOrganizationIdMap.getOrDefault("项目部检查", new BigDecimal("0"))).build(),
                            StatisticsNodeVo.builder().name("主体院检查").number(qualityNumberByOrganizationIdMap.getOrDefault("主体院检查", new BigDecimal("0"))).build(),
                            StatisticsNodeVo.builder().name("总院检查").number(qualityNumberByOrganizationIdMap.getOrDefault("总院检查", new BigDecimal("0"))).build(),
                            StatisticsNodeVo.builder().name("在建项目总数").number(constructingNum).build(),
                            StatisticsNodeVo.builder().name("项目平均检查数").number(constructingNum.compareTo(new BigDecimal("0")) == 0 ? new BigDecimal("0") : totalNum.divide(constructingNum, 1, RoundingMode.HALF_UP)).build())))
                    .build());
        }

        return statisticsNodeVos.stream().sorted(Comparator.comparing(StatisticsNodeVo::getDisplayOrder)).collect(Collectors.toList());
    }

    @Override
    public List<StatisticsNodeVo> getHiddenDangerInstituteStatics(HiddenDangerInstituteStatisticsCommand hiddenDangerInstituteStatisticsCommand) {
        List<StatisticsNodeVo> statisticsNodeVos = new ArrayList<>();

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<HiddenDangerVo>> allHiddenDangers = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());

        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return statisticsNodeVos;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allHiddenDangers.set(hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder().checkStartDateTime(hiddenDangerInstituteStatisticsCommand.getStartTime()).checkEndDateTime(hiddenDangerInstituteStatisticsCommand.getEndTime().minusSeconds(1L)).submitted(true).build())), IO_INSTANCE)
        ).join();

        Set<Long> safetyCheckIds = new HashSet<>();
        Map<Long, Long> dangerIdCheckIdMap = new HashMap<>();
        for (HiddenDangerVo hiddenDanger : allHiddenDangers.get()) {
            safetyCheckIds.add(hiddenDanger.getSafetyCheckId());
            dangerIdCheckIdMap.put(hiddenDanger.getId(), hiddenDanger.getSafetyCheckId());
        }

        allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder().ids(new ArrayList<>(safetyCheckIds)).build()));
        Map<Long, SafetyCheckVo> idSafetyCheckMap = new HashMap<>();
        for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
            idSafetyCheckMap.put(safetyCheckVo.getId(), safetyCheckVo);
        }

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>();
        Map<Long, List<Long>> organizationIdProjectIdsMap = new HashMap<>();
        for (ProjectResp projectResp : allProjects.get()) {
            projectIdOrganizationIdMap.put(projectResp.getId(), projectResp.getHrOrganizationId());
            List<Long> projectIdsByOrganizationId = organizationIdProjectIdsMap.getOrDefault(projectResp.getHrOrganizationId(), new ArrayList<>());
            projectIdsByOrganizationId.add(projectResp.getId());
            organizationIdProjectIdsMap.put(projectResp.getHrOrganizationId(), projectIdsByOrganizationId);
        }

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        Map<Long, Map<String, BigDecimal>> organizationIdNameNumberMapMap = new HashMap<>();
        for (HiddenDangerVo hiddenDangerVo : allHiddenDangers.get()) {
            Long hiddenDangerId = hiddenDangerVo.getId();
            Long safetyCheckId = dangerIdCheckIdMap.get(hiddenDangerId);
            if (null == safetyCheckId) {
                continue;
            }
            SafetyCheckVo safetyCheck = idSafetyCheckMap.get(safetyCheckId);
            if (null == safetyCheck || !verifyHelper.isAvailable(safetyCheck.getSafetyCheckQuality())) {
                continue;
            }
            Long projectId = hiddenDangerVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            String name = "";
            if (hiddenDangerVo.getOverdueStatus().equals("正常")) {
                name = safetyCheck.getSafetyCheckQuality() + "（按时整改隐患）";
            }
            if (hiddenDangerVo.getOverdueStatus().equals("超期完成") || hiddenDangerVo.getOverdueStatus().equals("超期未完成")) {
                name = safetyCheck.getSafetyCheckQuality() + "（超时整改隐患）";
            }
            Map<String, BigDecimal> nameNumberByOrganizationIdMap = organizationIdNameNumberMapMap.getOrDefault(organizationId, new HashMap<>());
            BigDecimal numberByOrganizationIdAndName = nameNumberByOrganizationIdMap.getOrDefault(name, new BigDecimal("0"));
            numberByOrganizationIdAndName = numberByOrganizationIdAndName.add(new BigDecimal("1"));
            nameNumberByOrganizationIdMap.put(name, numberByOrganizationIdAndName);
            organizationIdNameNumberMapMap.put(organizationId, nameNumberByOrganizationIdMap);
        }

        for (OrganizationResp organization : allOrganizations.get()) {
            if (!organization.getType().equals(HrOrganizationTypeEnum.PROJECT_MANAGEMENT_ORGANIZATION.name())) {
                continue;
            }
            Map<String, BigDecimal> nameNumberByOrganizationIdMap = organizationIdNameNumberMapMap.getOrDefault(organization.getId(), new HashMap<>());

            BigDecimal dangerProjectInTime = nameNumberByOrganizationIdMap.getOrDefault("项目部检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerProjectOutTime = nameNumberByOrganizationIdMap.getOrDefault("项目部检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerOrganizationInTime = nameNumberByOrganizationIdMap.getOrDefault("主体院检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerOrganizationOutTime = nameNumberByOrganizationIdMap.getOrDefault("主体院检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerInstituteInTime = nameNumberByOrganizationIdMap.getOrDefault("总院检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerInstituteOutTime = nameNumberByOrganizationIdMap.getOrDefault("总院检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal totalTime = dangerProjectInTime.add(dangerProjectOutTime).add(dangerOrganizationInTime).add(dangerOrganizationOutTime).add(dangerInstituteInTime).add(dangerInstituteOutTime);
            BigDecimal constructingNum = new BigDecimal(organizationIdProjectIdsMap.getOrDefault(organization.getId(), new ArrayList<>()).size());

            statisticsNodeVos.add(StatisticsNodeVo.builder()
                    .name(organization.getShortName())
                    .number(totalTime)
                    .displayOrder(organization.getDisplayOrder())
                    .statisticsNodes(new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name("项目部检查（按时整改隐患）").number(dangerProjectInTime).build(),
                            StatisticsNodeVo.builder().name("项目部检查（超时整改隐患）").number(dangerProjectOutTime).build(),
                            StatisticsNodeVo.builder().name("主体院检查（按时整改隐患）").number(dangerOrganizationInTime).build(),
                            StatisticsNodeVo.builder().name("主体院检查（超时整改隐患）").number(dangerOrganizationOutTime).build(),
                            StatisticsNodeVo.builder().name("总院检查（按时整改隐患）").number(dangerInstituteInTime).build(),
                            StatisticsNodeVo.builder().name("总院检查（超时整改隐患）").number(dangerInstituteOutTime).build(),
                            StatisticsNodeVo.builder().name("在建项目总数").number(constructingNum).build(),
                            StatisticsNodeVo.builder().name("项目平均隐患数").number(constructingNum.compareTo(new BigDecimal("0")) == 0 ? new BigDecimal("0") : totalTime.divide(constructingNum, 1, RoundingMode.HALF_UP)).build())))
                    .build());
        }

        return statisticsNodeVos.stream().sorted(Comparator.comparing(StatisticsNodeVo::getDisplayOrder)).collect(Collectors.toList());
    }

    @Override
    public List<StatisticsNodeVo> getHiddenDangerOrganizationStatics(HiddenDangerOrganizationStatisticsCommand hiddenDangerOrganizationStatisticsCommand) {
        List<StatisticsNodeVo> statisticsNodeVos = new ArrayList<>();

        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<HiddenDangerVo>> allHiddenDangers = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<SafetyCheckVo>> allSafetyChecks = new AtomicReference<>(new ArrayList<>());

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return statisticsNodeVos;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allHiddenDangers.set(hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder().checkStartDateTime(hiddenDangerOrganizationStatisticsCommand.getStartTime()).checkEndDateTime(hiddenDangerOrganizationStatisticsCommand.getEndTime().minusSeconds(1L)).submitted(true).build())), IO_INSTANCE)
        ).join();

        Set<Long> safetyCheckIds = new HashSet<>();
        Map<Long, Long> dangerIdCheckIdMap = new HashMap<>();
        for (HiddenDangerVo hiddenDanger : allHiddenDangers.get()) {
            safetyCheckIds.add(hiddenDanger.getSafetyCheckId());
            dangerIdCheckIdMap.put(hiddenDanger.getId(), hiddenDanger.getSafetyCheckId());
        }

        allSafetyChecks.set(safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder().ids(new ArrayList<>(safetyCheckIds)).build()));
        Map<Long, SafetyCheckVo> idSafetyCheckMap = new HashMap<>();
        for (SafetyCheckVo safetyCheckVo : allSafetyChecks.get()) {
            idSafetyCheckMap.put(safetyCheckVo.getId(), safetyCheckVo);
        }

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        Map<Long, Map<String, BigDecimal>> projectIdNameNumberMapMap = new HashMap<>();
        for (HiddenDangerVo hiddenDangerVo : allHiddenDangers.get()) {
            Long hiddenDangerId = hiddenDangerVo.getId();
            Long safetyCheckId = dangerIdCheckIdMap.get(hiddenDangerId);
            if (null == safetyCheckId) {
                continue;
            }
            SafetyCheckVo safetyCheck = idSafetyCheckMap.get(safetyCheckId);
            if (null == safetyCheck || !verifyHelper.isAvailable(safetyCheck.getSafetyCheckQuality())) {
                continue;
            }
            Long projectId = hiddenDangerVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            String name = "";
            if (hiddenDangerVo.getOverdueStatus().equals("正常")) {
                name = safetyCheck.getSafetyCheckQuality() + "（按时整改隐患）";
            }
            if (hiddenDangerVo.getOverdueStatus().equals("超期完成") || hiddenDangerVo.getOverdueStatus().equals("超期未完成")) {
                name = safetyCheck.getSafetyCheckQuality() + "（超时整改隐患）";
            }
            Map<String, BigDecimal> nameNumberByOrganizationIdMap = projectIdNameNumberMapMap.getOrDefault(projectId, new HashMap<>());
            BigDecimal numberByProjectIdAndName = nameNumberByOrganizationIdMap.getOrDefault(name, new BigDecimal("0"));
            numberByProjectIdAndName = numberByProjectIdAndName.add(new BigDecimal("1"));
            nameNumberByOrganizationIdMap.put(name, numberByProjectIdAndName);
            projectIdNameNumberMapMap.put(projectId, nameNumberByOrganizationIdMap);
        }

        for (ProjectResp project : allProjects.get()) {
            Map<String, BigDecimal> nameNumberByProjectIdMap = projectIdNameNumberMapMap.getOrDefault(project.getId(), new HashMap<>());

            BigDecimal dangerProjectInTime = nameNumberByProjectIdMap.getOrDefault("项目部检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerProjectOutTime = nameNumberByProjectIdMap.getOrDefault("项目部检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerOrganizationInTime = nameNumberByProjectIdMap.getOrDefault("主体院检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerOrganizationOutTime = nameNumberByProjectIdMap.getOrDefault("主体院检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerInstituteInTime = nameNumberByProjectIdMap.getOrDefault("总院检查（按时整改隐患）", new BigDecimal("0"));
            BigDecimal dangerInstituteOutTime = nameNumberByProjectIdMap.getOrDefault("总院检查（超时整改隐患）", new BigDecimal("0"));
            BigDecimal totalTime = dangerProjectInTime.add(dangerProjectOutTime).add(dangerOrganizationInTime).add(dangerOrganizationOutTime).add(dangerInstituteInTime).add(dangerInstituteOutTime);

            statisticsNodeVos.add(StatisticsNodeVo.builder()
                    .name(project.getProjectShortName())
                    .number(totalTime)
                    .displayOrder(project.getId().intValue())
                    .statisticsNodes(new ArrayList<>(Arrays.asList(StatisticsNodeVo.builder().name("项目部检查（按时整改隐患）").number(dangerProjectInTime).build(),
                            StatisticsNodeVo.builder().name("项目部检查（超时整改隐患）").number(dangerProjectOutTime).build(),
                            StatisticsNodeVo.builder().name("主体院检查（按时整改隐患）").number(dangerOrganizationInTime).build(),
                            StatisticsNodeVo.builder().name("主体院检查（超时整改隐患）").number(dangerOrganizationOutTime).build(),
                            StatisticsNodeVo.builder().name("总院检查（按时整改隐患）").number(dangerInstituteInTime).build(),
                            StatisticsNodeVo.builder().name("总院检查（超时整改隐患）").number(dangerInstituteOutTime).build())))
                    .build());
        }

        return statisticsNodeVos.stream().sorted(Comparator.comparing(StatisticsNodeVo::getDisplayOrder)).collect(Collectors.toList());
    }

    @Override
    public SafetyBoardOverviewVo getSafetyBoardOverview() {

        BigDecimal safetyCheckTotalNum = new BigDecimal("0");
        BigDecimal safetyCheckWeekNum = new BigDecimal("0");
        BigDecimal safetyCheckMonthNum = new BigDecimal("0");
        BigDecimal safetyEducationTotalNum = new BigDecimal("0");
        BigDecimal safetyEducationWeekNum = new BigDecimal("0");
        BigDecimal safetyEducationMonthNum = new BigDecimal("0");
        BigDecimal laborTotalNum = new BigDecimal("0");
        BigDecimal laborPresent = new BigDecimal("0");
        BigDecimal laborLeft = new BigDecimal("0");
        BigDecimal videoMonitorTotalNum = new BigDecimal("0");
        BigDecimal videoMonitorExistNum = new BigDecimal("0");
        BigDecimal videoMonitorNotNeedNum = new BigDecimal("0");
        BigDecimal videoMonitorInlineNum = new BigDecimal("0");
        BigDecimal majorHazardTotalNum = new BigDecimal("0");
        BigDecimal majorHazardWeekNum = new BigDecimal("0");
        BigDecimal majorHazardMonthNum = new BigDecimal("0");
        BigDecimal dangerSourceTotalNum = new BigDecimal("0");
        BigDecimal dangerSourceWeekNum = new BigDecimal("0");
        BigDecimal dangerSourceMonthNum = new BigDecimal("0");

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return SafetyBoardOverviewVo.builder()
                    .safetyCheckTotalNum(safetyCheckTotalNum)
                    .safetyCheckWeekNum(safetyCheckWeekNum)
                    .safetyCheckMonthNum(safetyCheckMonthNum)
                    .safetyEducationTotalNum(safetyEducationTotalNum)
                    .safetyEducationWeekNum(safetyEducationWeekNum)
                    .safetyEducationMonthNum(safetyEducationMonthNum)
                    .laborTotalNum(laborTotalNum)
                    .laborPresent(laborPresent)
                    .laborLeft(laborLeft)
                    .videoMonitorTotalNum(videoMonitorTotalNum)
                    .videoMonitorExistNum(videoMonitorExistNum)
                    .videoMonitorNotNeedNum(videoMonitorNotNeedNum)
                    .videoMonitorInlineNum(videoMonitorInlineNum)
                    .majorHazardTotalNum(majorHazardTotalNum)
                    .majorHazardWeekNum(majorHazardWeekNum)
                    .majorHazardMonthNum(majorHazardMonthNum)
                    .DangerSourceTotalNum(dangerSourceTotalNum)
                    .DangerSourceWeekNum(dangerSourceWeekNum)
                    .DangerSourceMonthNum(dangerSourceMonthNum)
                    .build();
        }

        AtomicInteger safetyCheckTotalCount = new AtomicInteger(0);
        AtomicInteger safetyCheckWeekCount = new AtomicInteger(0);
        AtomicInteger safetyCheckMonthCount = new AtomicInteger(0);
        AtomicInteger safetyEducationTotalCount = new AtomicInteger(0);
        AtomicInteger safetyEducationWeekCount = new AtomicInteger(0);
        AtomicInteger safetyEducationMonthCount = new AtomicInteger(0);
        AtomicInteger laborTotalCount = new AtomicInteger(0);
        AtomicInteger laborPresentCount = new AtomicInteger(0);
        AtomicInteger laborLeftCount = new AtomicInteger(0);
        AtomicInteger videoMonitorTotalCount = new AtomicInteger(0);
        AtomicInteger videoMonitorExistCount = new AtomicInteger(0);
        AtomicInteger videoMonitorNotNeedCount = new AtomicInteger(0);
        AtomicInteger videoMonitorInlineCount = new AtomicInteger(0);
        AtomicInteger majorHazardTotalCount = new AtomicInteger(0);
        AtomicInteger majorHazardWeekCount = new AtomicInteger(0);
        AtomicInteger majorHazardMonthCount = new AtomicInteger(0);
        AtomicInteger dangerSourceTotalCount = new AtomicInteger(0);
        AtomicInteger dangerSourceWeekCount = new AtomicInteger(0);
        AtomicInteger dangerSourceMonthCount = new AtomicInteger(0);

        // 本周第一天和本月第一天
        LocalDate weekFirstDay = LocalDate.now().with(DayOfWeek.MONDAY);
        LocalDate weekEndDay = LocalDate.now().with(DayOfWeek.MONDAY).plusDays(6L);
        LocalDate monthFirstDay = LocalDate.now().withDayOfMonth(1);
        LocalDate monthEndDay = LocalDate.now().withDayOfMonth(1).plusMonths(1L).minusDays(1L);

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> {
                    MonitorSettingCountResponse monitorSettingCountResponse = videoMonitorRemoteApi.getProjectMonitorSettingCount(projectIds);
                    videoMonitorTotalCount.set(monitorSettingCountResponse.getAllNum());
                    videoMonitorInlineCount.set(monitorSettingCountResponse.getOnLineNum());
                    videoMonitorExistCount.set(monitorSettingCountResponse.getExistsProjectNum());
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    List<String> monitorTypeList = new ArrayList<>();
                    monitorTypeList.add(NOT_INSTALLED.name());
                    monitorTypeList.add(STOPPED.name());
                    videoMonitorNotNeedCount.set(projectRemoteService.getProjectCount(ProjectQuery.builder().ids(projectIds).monitorTypes(monitorTypeList).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyCheckTotalCount.set(safetyCheckRemoteApi.getSafetyCheckCount(SafetyCheckQuery.builder().projectIds(projectIds).submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyCheckMonthCount.set(safetyCheckRemoteApi.getSafetyCheckCount(SafetyCheckQuery.builder().projectIds(projectIds).checkStartDateTime(monthFirstDay.atTime(0, 0, 0)).checkEndDateTime(monthEndDay.atTime(23, 59, 59)).submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyCheckWeekCount.set(safetyCheckRemoteApi.getSafetyCheckCount(SafetyCheckQuery.builder().projectIds(projectIds).checkStartDateTime(weekFirstDay.atStartOfDay()).checkEndDateTime(weekEndDay.atTime(23, 59, 59)).submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyEducationTotalCount.set(safetyEducationRemoteApi.getSafetyEducationCount(SafetyEducationQuery.builder().submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyEducationWeekCount.set(safetyEducationRemoteApi.getSafetyEducationCount(SafetyEducationQuery.builder().educationStartTime(weekFirstDay.atTime(0, 0, 0)).educationEndTime(weekEndDay.atTime(23, 59, 59)).submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    safetyEducationMonthCount.set(safetyEducationRemoteApi.getSafetyEducationCount(SafetyEducationQuery.builder().educationStartTime(monthFirstDay.atTime(0, 0, 0)).educationEndTime(monthEndDay.atTime(0, 0, 0)).submitted(true).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    laborTotalCount.set(laborRemoteApi.getLaborCount(LaborQuery.builder().build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    laborPresentCount.set(laborRemoteApi.getLaborCount(LaborQuery.builder().status("IN").build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    laborLeftCount.set(laborTotalCount.get() - laborPresentCount.get());
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    majorHazardTotalCount.set(majorHazardRemoteApi.getMajorHazardCount(MajorHazardQuery.builder().build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    majorHazardWeekCount.set(majorHazardRemoteApi.getMajorHazardCountByTimeLine(TimeLineQuery.builder().startTime(weekFirstDay).endTime(weekEndDay).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    majorHazardMonthCount.set(majorHazardRemoteApi.getMajorHazardCountByTimeLine(TimeLineQuery.builder().startTime(monthFirstDay).endTime(monthEndDay).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    dangerSourceTotalCount.set(dangerSourceRemoteApi.getDangerSourceCount(DangerSourceQuery.builder().build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    dangerSourceWeekCount.set(dangerSourceRemoteApi.getMajorHazardCountByTimeLine(TimeLineQuery.builder().startTime(weekFirstDay).endTime(weekEndDay).build()));
                }, IO_INSTANCE),

                CompletableFuture.runAsync(() -> {
                    dangerSourceMonthCount.set(dangerSourceRemoteApi.getMajorHazardCountByTimeLine(TimeLineQuery.builder().startTime(monthFirstDay).endTime(monthEndDay).build()));
                }, IO_INSTANCE)
        ).join();
        return SafetyBoardOverviewVo.builder()
                .safetyCheckTotalNum(safetyCheckTotalNum.add(new BigDecimal(safetyCheckTotalCount.get())))
                .safetyCheckWeekNum(safetyCheckWeekNum.add(new BigDecimal(safetyCheckWeekCount.get())))
                .safetyCheckMonthNum(safetyCheckMonthNum.add(new BigDecimal(safetyCheckMonthCount.get())))
                .safetyEducationTotalNum(safetyEducationTotalNum.add(new BigDecimal(safetyEducationTotalCount.get())))
                .safetyEducationWeekNum(safetyEducationWeekNum.add(new BigDecimal(safetyEducationWeekCount.get())))
                .safetyEducationMonthNum(safetyEducationMonthNum.add(new BigDecimal(safetyEducationMonthCount.get())))
                .laborTotalNum(laborTotalNum.add(new BigDecimal(laborTotalCount.get())))
                .laborPresent(laborPresent.add(new BigDecimal(laborPresentCount.get())))
                .laborLeft(laborLeft.add(new BigDecimal(laborLeftCount.get())))
                .videoMonitorTotalNum(videoMonitorTotalNum.add(new BigDecimal(videoMonitorTotalCount.get())))
                .videoMonitorExistNum(videoMonitorExistNum.add(new BigDecimal(videoMonitorExistCount.get())))
                .videoMonitorNotNeedNum(videoMonitorNotNeedNum.add(new BigDecimal(videoMonitorNotNeedCount.get())))
                .videoMonitorInlineNum(videoMonitorInlineNum.add(new BigDecimal(videoMonitorInlineCount.get())))
                .majorHazardTotalNum(majorHazardTotalNum.add(new BigDecimal(majorHazardTotalCount.get())))
                .majorHazardWeekNum(majorHazardWeekNum.add(new BigDecimal(majorHazardWeekCount.get())))
                .majorHazardMonthNum(majorHazardMonthNum.add(new BigDecimal(majorHazardMonthCount.get())))
                .DangerSourceTotalNum(dangerSourceTotalNum.add(new BigDecimal(dangerSourceTotalCount.get())))
                .DangerSourceWeekNum(dangerSourceWeekNum.add(new BigDecimal(dangerSourceWeekCount.get())))
                .DangerSourceMonthNum(dangerSourceMonthNum.add(new BigDecimal(dangerSourceMonthCount.get())))
                .build();
    }

    @Override
    public MajorHazardPageVo getTodayMajorHazardPage(MajorHazardTodayPageCommand majorHazardTodayPageCommand) {

        List<MajorHazardVo> records = new ArrayList<>();
        BigDecimal disclosureNum = new BigDecimal("0");
        BigDecimal notDisclosureNum = new BigDecimal("0");
        BigDecimal notNeedDisclosureNum = new BigDecimal("0");
        BigDecimal total = new BigDecimal("0");

        MajorHazardPageVo majorHazardPageVo = MajorHazardPageVo.builder()
                .current(majorHazardTodayPageCommand.getCurrent())
                .size(majorHazardTodayPageCommand.getSize())
                .total(total)
                .records(records)
                .disclosureNum(disclosureNum)
                .notDisclosureNum(notDisclosureNum)
                .notNeedDisclosureNum(notNeedDisclosureNum)
                .build();

        long offset = (majorHazardTodayPageCommand.getCurrent() - 1) * majorHazardTodayPageCommand.getSize();
        long limit = majorHazardTodayPageCommand.getCurrent() * majorHazardTodayPageCommand.getSize();

        List<Long> organizationIds = authorityUtil.getDataScope().getOrDefault(ACCESS_HR_ORGANIZATION, new ArrayList<>());
        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return majorHazardPageVo;
        }

        AtomicReference<List<OrganizationResp>> allOrganizations = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<MajorHazardVo>> allMajorHazards = new AtomicReference<>(new ArrayList<>());

        LocalDateTime startTime = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endTime = LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1L).minusSeconds(1L);

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allOrganizations.set(organizationRemoteService.getOrganizationList(OrganizationQuery.builder().ids(organizationIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allMajorHazards.set(majorHazardRemoteApi.getMajorHazardList(MajorHazardQuery.builder().planConstructionTimeEnd(startTime).planEndTimeStart(endTime).build())), IO_INSTANCE)
        ).join();

        Map<Long, Long> projectIdOrganizationIdMap = new HashMap<>();
        for (ProjectResp projectResp : allProjects.get()) {
            projectIdOrganizationIdMap.put(projectResp.getId(), projectResp.getHrOrganizationId());
        }

        Map<Long, OrganizationResp> organizationIdOrganizationMap = new HashMap<>();
        for (OrganizationResp organizationResp : allOrganizations.get()) {
            organizationIdOrganizationMap.put(organizationResp.getId(), organizationResp);
        }

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        List<MajorHazardVo> majorHazardVos = new ArrayList<>();
        for (MajorHazardVo majorHazardVo : allMajorHazards.get()) {
            Long projectId = majorHazardVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            Long organizationId = projectIdOrganizationIdMap.get(projectId);
            OrganizationResp organization = organizationIdOrganizationMap.get(organizationId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            majorHazardVo.setProjectName(project.getProjectShortName());
            majorHazardVo.setProjectDisplayOrder(project.getId().intValue());
            if (null != organization) {
                majorHazardVo.setOrganizationName(organization.getShortName());
                majorHazardVo.setOrganizationDisplayOrder(organization.getDisplayOrder());
            }

            majorHazardVos.add(majorHazardVo);

            total = total.add(new BigDecimal("1"));
        }

        List<MajorHazardVo> majorHazards = majorHazardVos.stream().sorted(Comparator.comparing(MajorHazardVo::getOrganizationDisplayOrder).reversed().thenComparing(MajorHazardVo::getProjectDisplayOrder).reversed()).collect(Collectors.toList());

        int i = 0;

        for (MajorHazardVo majorHazardVo : majorHazards) {
            if (i >= offset && i < limit) {
                records.add(majorHazardVo);
            }
            if (majorHazardVo.getConfessionStatus().equals("0")) {
                notDisclosureNum = notDisclosureNum.add(new BigDecimal("1"));
            }
            if (majorHazardVo.getConfessionStatus().equals("1")) {
                disclosureNum = disclosureNum.add(new BigDecimal("1"));
            }
            if (majorHazardVo.getConfessionStatus().equals("2")) {
                notNeedDisclosureNum = notNeedDisclosureNum.add(new BigDecimal("1"));
            }
            i = i + 1;
        }

        return MajorHazardPageVo.builder()
                .current(majorHazardTodayPageCommand.getCurrent())
                .size(majorHazardTodayPageCommand.getSize())
                .total(total)
                .records(records)
                .disclosureNum(disclosureNum)
                .notDisclosureNum(notDisclosureNum)
                .notNeedDisclosureNum(notNeedDisclosureNum)
                .build();
    }

    @Override
    public DangerSourcePageVo getTodayDangerSourcePage(DangerSourceTodayPageCommand dangerSourceTodayPageCommand) {

        DangerSourcePageVo dangerSourcePageVo = DangerSourcePageVo.builder()
                .current(dangerSourceTodayPageCommand.getCurrent())
                .size(dangerSourceTodayPageCommand.getSize())
                .total(new BigDecimal("0"))
                .records(new ArrayList<>())
                .build();

        List<DangerSourceVo> records = new ArrayList<>();
        BigDecimal total = new BigDecimal("0");

        long offset = (dangerSourceTodayPageCommand.getCurrent() - 1) * dangerSourceTodayPageCommand.getSize();
        long limit = dangerSourceTodayPageCommand.getCurrent() * dangerSourceTodayPageCommand.getSize();

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return dangerSourcePageVo;
        }

        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<DangerSourceVo>> allDangerSources = new AtomicReference<>(new ArrayList<>());

        LocalDateTime startTime = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endTime = LocalDateTime.now().toLocalDate().atStartOfDay().plusDays(1L).minusSeconds(1L);

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allDangerSources.set(dangerSourceRemoteApi.getDangerSourceList(DangerSourceQuery.builder().planConstructionTimeEnd(startTime).planEndTimeStart(endTime).build())), IO_INSTANCE)
        ).join();

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        List<DangerSourceVo> dangerSourceVos = new ArrayList<>();
        for (DangerSourceVo dangerSourceVo : allDangerSources.get()) {
            Long projectId = dangerSourceVo.getProjectId();
            ProjectResp project = projectIdProjectMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            dangerSourceVos.add(dangerSourceVo);

            total = total.add(new BigDecimal("1"));
        }

        dangerSourceVos = dangerSourceVos.stream().sorted(Comparator.comparing(DangerSourceVo::getProjectId)).collect(Collectors.toList());

        int i = 0;

        for (DangerSourceVo dangerSourceVo : dangerSourceVos) {
            if (i >= offset && i < limit) {
                records.add(dangerSourceVo);
            }
            i = i + 1;
        }

        return DangerSourcePageVo.builder()
                .current(dangerSourceTodayPageCommand.getCurrent())
                .size(dangerSourceTodayPageCommand.getSize())
                .total(total)
                .records(records)
                .build();
    }

    @Override
    public HiddenDangerStatisticsVo getHiddenDangerStatistics(HiddenDangerStatisticsCommand hiddenDangerStatisticsCommand) {

        HiddenDangerStatisticsVo hiddenDangerStatisticsVo = HiddenDangerStatisticsVo.builder()
                .hiddenDangerCategoryInfos(new ArrayList<>())
                .totalNum(new BigDecimal("0"))
                .build();

        List<StatisticsInfoVo> hiddenDangerCategoryInfos = new ArrayList<>();

        AtomicReference<List<ProjectResp>> allProjects = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<HiddenDangerVo>> allHiddenDangers = new AtomicReference<>(new ArrayList<>());

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return hiddenDangerStatisticsVo;
        }

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> allProjects.set(projectRemoteService.getProjectList(ProjectQuery.builder().ids(projectIds).build())), IO_INSTANCE),
                CompletableFuture.runAsync(() -> allHiddenDangers.set(hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder().checkStartDateTime(hiddenDangerStatisticsCommand.getStartTime()).checkEndDateTime(hiddenDangerStatisticsCommand.getEndTime().minusSeconds(1L)).submitted(true).build())), IO_INSTANCE)
        ).join();

        Map<Long, ProjectResp> projectIdProjectMap = new HashMap<>(128);
        for (ProjectResp project : allProjects.get()) {
            projectIdProjectMap.put(project.getId(), project);
        }

        Map<String, StatisticsInfoVo> categoryCategoryInfoMap = new HashMap<>(128);
        BigDecimal totalNum = new BigDecimal("0");

        for (HiddenDangerVo hiddenDangerVo : allHiddenDangers.get()) {
            Long projectId = hiddenDangerVo.getProjectId();
            if (null == projectId) {
                continue;
            }
            ProjectResp project = projectIdProjectMap.get(projectId);
            if (!project.getProjectStatus().equals(CONSTRUCTING.name())) {
                continue;
            }
            // 总数
            totalNum = totalNum.add(new BigDecimal("1"));

            // 统计种类信息
            String hiddenDangerCategory = hiddenDangerVo.getHiddenDangerCategory();
            StatisticsInfoVo categoryInfoByCategory = categoryCategoryInfoMap.getOrDefault(hiddenDangerCategory, StatisticsInfoVo.builder().name(hiddenDangerCategory).number(new BigDecimal("0")).build());
            categoryInfoByCategory.setNumber(categoryInfoByCategory.getNumber().add(new BigDecimal("1")));
            categoryCategoryInfoMap.put(hiddenDangerCategory, categoryInfoByCategory);
        }

        hiddenDangerStatisticsVo.setTotalNum(totalNum);

        if (totalNum.compareTo(new BigDecimal("0")) == 0) {
            return hiddenDangerStatisticsVo;
        }

        // 装载主体院信息
        if (!categoryCategoryInfoMap.isEmpty()) {
            hiddenDangerCategoryInfos = categoryCategoryInfoMap.values().stream().sorted(Comparator.comparing(StatisticsInfoVo::getNumber).reversed()).collect(Collectors.toList());
            for (StatisticsInfoVo hiddenDangerCategoryInfo : hiddenDangerCategoryInfos) {
                hiddenDangerCategoryInfo.setRate(hiddenDangerCategoryInfo.getNumber().divide(totalNum, 3, RoundingMode.HALF_UP));
            }
        }

        hiddenDangerStatisticsVo.setHiddenDangerCategoryInfos(hiddenDangerCategoryInfos);
        hiddenDangerStatisticsVo.setTotalNum(totalNum);

        return hiddenDangerStatisticsVo;
    }

    @Override
    public List<HiddenDangerProjectStatisticsVo> getHiddenDangerProjectStatics(HiddenDangerProjectStatisticsCommand hiddenDangerProjectStatisticsCommand) {

        List<HiddenDangerProjectStatisticsVo> hiddenDangerProjectStatisticsVos = new ArrayList<>();

        int timeNumber = hiddenDangerProjectStatisticsCommand.getTimeNumber();

        if (timeNumber <= 0) {
            return hiddenDangerProjectStatisticsVos;
        }

        // 获取起始时间和结束时间
        LocalDateTime end = LocalDateTime.now();

        LocalDateTime monthFirstDay;

        monthFirstDay = end.withDayOfMonth(1).toLocalDate().atStartOfDay().minusSeconds(1L);
        LocalDateTime start = monthFirstDay.minusMonths(timeNumber - 1);


        for (int i = 0; i < timeNumber; i++) {
            HiddenDangerProjectStatisticsVo hiddenDangerProjectStatisticsVo = HiddenDangerProjectStatisticsVo.builder()
                    .totalNumber(new BigDecimal("0"))
                    .build();

            hiddenDangerProjectStatisticsVo.setStartTime(start.plusMonths(i));
            if (i == timeNumber - 1) {
                hiddenDangerProjectStatisticsVo.setEndTime(end);
            }
            if (i != timeNumber - 1) {
                hiddenDangerProjectStatisticsVo.setEndTime(start.plusMonths(i + 1));
            }

            hiddenDangerProjectStatisticsVos.add(hiddenDangerProjectStatisticsVo);
        }

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return hiddenDangerProjectStatisticsVos;
        }

        List<HiddenDangerVo> allHiddenDangers = hiddenDangerRemoteApi.getHiddenDangerList(HiddenDangerQuery.builder().checkStartDateTime(start.toLocalDate().atStartOfDay()).checkEndDateTime(end).submitted(true).build());

        for (HiddenDangerVo hiddenDangerVo : allHiddenDangers) {
            for (HiddenDangerProjectStatisticsVo hiddenDangerProjectStatisticsVo : hiddenDangerProjectStatisticsVos) {
                if ((hiddenDangerVo.getCheckTime().isAfter(hiddenDangerProjectStatisticsVo.getStartTime()) || hiddenDangerVo.getCheckTime().equals(hiddenDangerProjectStatisticsVo.getStartTime())) && hiddenDangerVo.getCheckTime().isBefore(hiddenDangerProjectStatisticsVo.getEndTime())) {
                    hiddenDangerProjectStatisticsVo.setTotalNumber(hiddenDangerProjectStatisticsVo.getTotalNumber().add(new BigDecimal("1")));
                }
            }
        }

        return hiddenDangerProjectStatisticsVos;
    }

    @Override
    public List<SafetyCheckProjectStatisticsVo> getSafetyCheckProjectStatics(SafetyCheckProjectStatisticsCommand safetyCheckProjectStatisticsCommand) {

        List<SafetyCheckProjectStatisticsVo> safetyCheckProjectStatisticsVos = new ArrayList<>();

        String timeType = safetyCheckProjectStatisticsCommand.getTimeType();
        int timeNumber = safetyCheckProjectStatisticsCommand.getTimeNumber();

        if (timeNumber <= 0) {
            return safetyCheckProjectStatisticsVos;
        }

        // 获取起始时间和结束时间
        LocalDateTime end = LocalDateTime.now();
        LocalDateTime weekFirstDay;
        LocalDateTime monthFirstDay;
        LocalDateTime quarterFirstDay;
        LocalDateTime start = LocalDateTime.now();

        if (timeType.equals(WEEK.name())) {
            weekFirstDay = end.with(DayOfWeek.MONDAY).toLocalDate().atStartOfDay();
            start = weekFirstDay.minusDays(7L * (timeNumber - 1));
        }
        if (timeType.equals(MONTH.name())) {
            monthFirstDay = end.withDayOfMonth(1).toLocalDate().atStartOfDay();
            start = monthFirstDay.minusMonths(timeNumber - 1);
        }
        if (timeType.equals(QUARTER.name())) {
            monthFirstDay = end.withDayOfMonth(1).toLocalDate().atStartOfDay();
            BigDecimal month = new BigDecimal(monthFirstDay.getMonthValue());
            quarterFirstDay = LocalDate.of(monthFirstDay.getYear(), month.subtract(month.subtract(new BigDecimal("1")).divideAndRemainder(new BigDecimal("3"))[1]).intValue(), 1).atStartOfDay();
            start = quarterFirstDay.minusMonths(3L * (timeNumber - 1));
        }

        for (int i = 0; i < timeNumber; i++) {
            SafetyCheckProjectStatisticsVo safetyCheckProjectStatisticsVo = SafetyCheckProjectStatisticsVo.builder()
                    .checkProjectNumber(new BigDecimal("0"))
                    .checkOrganizationNumber(new BigDecimal("0"))
                    .checkInstituteNumber(new BigDecimal("0"))
                    .totalNumber(new BigDecimal("0"))
                    .build();
            if (timeType.equals(WEEK.name())) {
                safetyCheckProjectStatisticsVo.setStartTime(start.plusDays(i * 7L));
                safetyCheckProjectStatisticsVo.setEndTime(start.plusDays((i + 1) * 7L));
            }
            if (timeType.equals(MONTH.name())) {
                safetyCheckProjectStatisticsVo.setStartTime(start.plusMonths(i));
                safetyCheckProjectStatisticsVo.setEndTime(start.plusMonths(i + 1));
            }
            if (timeType.equals(QUARTER.name())) {
                safetyCheckProjectStatisticsVo.setStartTime(start.plusMonths(i * 3L));
                safetyCheckProjectStatisticsVo.setEndTime(start.plusMonths((i + 1) * 3L));
            }
            safetyCheckProjectStatisticsVos.add(safetyCheckProjectStatisticsVo);
        }

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return safetyCheckProjectStatisticsVos;
        }

        List<SafetyCheckVo> allSafetyChecks = safetyCheckRemoteApi.getSafetyCheckList(SafetyCheckQuery.builder().checkStartDateTime(start.toLocalDate().atStartOfDay()).checkEndDateTime(end).submitted(true).build());

        for (SafetyCheckVo safetyCheckVo : allSafetyChecks) {
            for (SafetyCheckProjectStatisticsVo safetyCheckProjectStatisticsVo : safetyCheckProjectStatisticsVos) {
                if ((safetyCheckVo.getCheckTime().isAfter(safetyCheckProjectStatisticsVo.getStartTime().toLocalDate()) || safetyCheckVo.getCheckTime().equals(safetyCheckProjectStatisticsVo.getStartTime().toLocalDate())) && safetyCheckVo.getCheckTime().isBefore(safetyCheckProjectStatisticsVo.getEndTime().toLocalDate().plusDays(1L))) {
                    safetyCheckProjectStatisticsVo.setTotalNumber(safetyCheckProjectStatisticsVo.getTotalNumber().add(new BigDecimal("1")));
                    if (safetyCheckVo.getSafetyCheckQuality().equals("项目部检查")) {
                        safetyCheckProjectStatisticsVo.setCheckProjectNumber(safetyCheckProjectStatisticsVo.getCheckProjectNumber().add(new BigDecimal("1")));
                    }
                    if (safetyCheckVo.getSafetyCheckQuality().equals("主体院检查")) {
                        safetyCheckProjectStatisticsVo.setCheckOrganizationNumber(safetyCheckProjectStatisticsVo.getCheckOrganizationNumber().add(new BigDecimal("1")));
                    }
                    if (safetyCheckVo.getSafetyCheckQuality().equals("总院检查")) {
                        safetyCheckProjectStatisticsVo.setCheckInstituteNumber(safetyCheckProjectStatisticsVo.getCheckInstituteNumber().add(new BigDecimal("1")));
                    }
                }
            }
        }

        return safetyCheckProjectStatisticsVos;
    }

    @Override
    public List<SafetyEducationProjectStatisticsVo> getSafetyEducationProjectStatics(SafetyEducationProjectStatisticsCommand safetyEducationProjectStatisticsCommand) {

        List<SafetyEducationProjectStatisticsVo> safetyEducationProjectStatisticsVos = new ArrayList<>();

        String timeType = safetyEducationProjectStatisticsCommand.getTimeType();
        int timeNumber = safetyEducationProjectStatisticsCommand.getTimeNumber();

        if (timeNumber <= 0) {
            return safetyEducationProjectStatisticsVos;
        }

        // 获取起始时间和结束时间
        LocalDateTime end = LocalDateTime.now();
        LocalDateTime weekFirstDay;
        LocalDateTime monthFirstDay;
        LocalDateTime quarterFirstDay;
        LocalDateTime start = LocalDateTime.now();

        if (timeType.equals(WEEK.name())) {
            weekFirstDay = end.with(DayOfWeek.MONDAY).toLocalDate().atStartOfDay();
            start = weekFirstDay.minusDays(7L * (timeNumber - 1));
        }
        if (timeType.equals(MONTH.name())) {
            monthFirstDay = end.withDayOfMonth(1).toLocalDate().atStartOfDay();
            start = monthFirstDay.minusMonths(timeNumber - 1);
        }
        if (timeType.equals(QUARTER.name())) {
            monthFirstDay = end.withDayOfMonth(1).toLocalDate().atStartOfDay();
            BigDecimal month = new BigDecimal(monthFirstDay.getMonthValue());
            quarterFirstDay = LocalDate.of(monthFirstDay.getYear(), month.subtract(month.subtract(new BigDecimal("1")).divideAndRemainder(new BigDecimal("3"))[1]).intValue(), 1).atStartOfDay();
            start = quarterFirstDay.minusMonths(3L * (timeNumber - 1));
        }

        for (int i = 0; i < timeNumber; i++) {
            SafetyEducationProjectStatisticsVo safetyEducationProjectStatisticsVo = SafetyEducationProjectStatisticsVo.builder()
                    .dailyMorningNumber(new BigDecimal("0"))
                    .preFestivalNumber(new BigDecimal("0"))
                    .specialTrainingNumber(new BigDecimal("0"))
                    .build();
            if (timeType.equals(WEEK.name())) {
                safetyEducationProjectStatisticsVo.setStartTime(start.plusDays(i * 7L));
                safetyEducationProjectStatisticsVo.setEndTime(start.plusDays((i + 1) * 7L));
            }
            if (timeType.equals(MONTH.name())) {
                safetyEducationProjectStatisticsVo.setStartTime(start.plusMonths(i));
                safetyEducationProjectStatisticsVo.setEndTime(start.plusMonths(i + 1));
            }
            if (timeType.equals(QUARTER.name())) {
                safetyEducationProjectStatisticsVo.setStartTime(start.plusMonths(i * 3L));
                safetyEducationProjectStatisticsVo.setEndTime(start.plusMonths((i + 1) * 3L));
            }
            safetyEducationProjectStatisticsVos.add(safetyEducationProjectStatisticsVo);
        }

        List<Long> projectIds = authorityUtil.getDataScope().getOrDefault(ACCESS_PROJECT, new ArrayList<>());
        if (projectIds.isEmpty()) {
            return safetyEducationProjectStatisticsVos;
        }

        List<SafetyEducationVo> allSafetyEducations = safetyEducationRemoteApi.getSafetyEducationList(SafetyEducationQuery.builder().educationStartTime(start.toLocalDate().atStartOfDay()).educationEndTime(end).submitted(true).build());

        for (SafetyEducationVo safetyEducationVo : allSafetyEducations) {
            for (SafetyEducationProjectStatisticsVo safetyEducationProjectStatisticsVo : safetyEducationProjectStatisticsVos) {
                if ((safetyEducationVo.getEducationTime().isAfter(safetyEducationProjectStatisticsVo.getStartTime()) || safetyEducationVo.getEducationTime().equals(safetyEducationProjectStatisticsVo.getStartTime())) && safetyEducationVo.getEducationTime().isBefore(safetyEducationProjectStatisticsVo.getEndTime().plusDays(1L))) {
                    if (safetyEducationVo.getEducationType().equals(DAILY_MORNING.name())) {
                        safetyEducationProjectStatisticsVo.setDailyMorningNumber(safetyEducationProjectStatisticsVo.getDailyMorningNumber().add(new BigDecimal("1")));
                    }
                    if (safetyEducationVo.getEducationType().equals(PRE_FESTIVAL.name())) {
                        safetyEducationProjectStatisticsVo.setPreFestivalNumber(safetyEducationProjectStatisticsVo.getPreFestivalNumber().add(new BigDecimal("1")));
                    }
                    if (safetyEducationVo.getEducationType().equals(SPECIAL_TRAINING.name())) {
                        safetyEducationProjectStatisticsVo.setSpecialTrainingNumber(safetyEducationProjectStatisticsVo.getSpecialTrainingNumber().add(new BigDecimal("1")));
                    }
                }
            }
        }

        return safetyEducationProjectStatisticsVos;
    }
}
